const express = require("express");
const router = express.Router();
const { ethers } = require("ethers");
const { pool } = require("../config/db");
const logger = require("../utils/logger");
const authenticateToken = require("../middleware/auth");
const { getNetwork } = require("../config/networks");
// 导入NFT合约ABI并正确引用abi字段
const nftABIFile = require("../contract/abi/contracts/TestNFT.sol/TestNFT.json");
const nftABI = nftABIFile.abi;

// 铸造NFT的费用（固定值）
const MINT_NFT_FEE = 100; // 铸造一个NFT需要花费100单位的余额
// 备用简化版ABI
// const nftABI = [
//   "function mint(address to) external returns (uint256)",
//   "function balanceOf(address owner) external view returns (uint256)",
//   "function ownerOf(uint256 tokenId) external view returns (address)",
//   "function transferFrom(address from, address to, uint256 tokenId) external",
// ];

// 请求铸造NFT
router.post("/mint-nft", authenticateToken, async (req, res) => {
  try {
    const { nft_contract_address } = req.body;
    const userId = req.user.id;

    // 验证合约地址格式
    if (!ethers.utils.isAddress(nft_contract_address)) {
      return res.status(400).json({ message: "无效的NFT合约地址" });
    }

    // 获取用户钱包地址、余额和当前网络
    const [users] = await pool.query(
      "SELECT wallet_address, balance, current_chain FROM users WHERE id = ?",
      [userId]
    );
    if (users.length === 0) {
      return res.status(404).json({ message: "用户不存在" });
    }

    const userWalletAddress = users[0].wallet_address;
    const userBalance = users[0].balance || 0;

    if (!userWalletAddress) {
      return res.status(400).json({ message: "请先绑定钱包地址" });
    }

    // 检查用户余额是否足够
    if (userBalance < MINT_NFT_FEE) {
      return res.status(400).json({
        message: `余额不足，铸造NFT需要${MINT_NFT_FEE}单位余额，当前余额${userBalance}`,
      });
    }

    // 获取当前网络配置
    const networkId = users[0].current_chain || "ethereum";
    const network = getNetwork(networkId);

    // 连接区块链网络
    logger.info(`尝试使用RPC URL:${network.rpcUrl}连接${network.name}网络`);
    const provider = new ethers.providers.JsonRpcProvider(network.rpcUrl);

    // 测试网络连接
    try {
      await provider.getNetwork();
      logger.info(`成功连接到${network.name}网络`);
    } catch (networkError) {
      logger.error(`${network.name}网络连接失败: ${networkError.message}`, {
        error: networkError.stack,
      });
      return res
        .status(503)
        .json({ message: `无法连接到${network.name}网络，请稍后再试` });
    }

    if (!process.env.WALLET_PRIVATE_KEY) {
      logger.error("错误: 未设置WALLET_PRIVATE_KEY环境变量");
      return res
        .status(500)
        .json({ message: "服务器配置错误: 未设置钱包私钥" });
    }

    const adminWallet = new ethers.Wallet(
      process.env.WALLET_PRIVATE_KEY,
      provider
    );

    // 连接NFT合约
    const nftContract = new ethers.Contract(
      nft_contract_address,
      nftABI,
      adminWallet
    );

    // 记录交易到数据库（状态为pending）
    const [result] = await pool.query(
      "INSERT INTO transactions (user_id, transaction_type, token_address, status) VALUES (?, ?, ?, ?)",
      [userId, "mint_nft", nft_contract_address, "pending"]
    );
    const transactionId = result.insertId;

    // 铸造NFT
    const tx = await nftContract.safeMint(userWalletAddress);
    const receipt = await tx.wait();

    // 从事件中获取tokenId (这里简化处理，实际需要根据合约事件结构解析)
    // 假设合约有一个Transfer事件，包含tokenId
    const tokenId = receipt.logs[0].topics[3]; // 简化示例，实际需要正确解析事件

    // 开始事务
    const connection = await pool.getConnection();
    await connection.beginTransaction();

    try {
      // 更新交易记录
      await connection.query(
        "UPDATE transactions SET status = ?, transaction_hash = ?, token_id = ?, amount = ? WHERE id = ?",
        [
          "completed",
          receipt.transactionHash,
          tokenId,
          MINT_NFT_FEE,
          transactionId,
        ]
      );

      // 添加到用户资产
      await connection.query(
        "INSERT INTO assets (user_id, asset_type, token_address, token_id) VALUES (?, ?, ?, ?)",
        [userId, "nft", nft_contract_address, tokenId]
      );

      // 扣除用户余额
      await connection.query(
        "UPDATE users SET balance = balance - ? WHERE id = ?",
        [MINT_NFT_FEE, userId]
      );

      // 提交事务
      await connection.commit();
      connection.release();
    } catch (error) {
      // 回滚事务
      await connection.rollback();
      connection.release();
      throw error;
    }

    res.json({
      message: "NFT铸造成功",
      transaction_hash: receipt.transactionHash,
      token_id: tokenId,
    });
  } catch (error) {
    logger.error(`铸造NFT错误: ${error.message}`, { error: error.stack });
    res.status(500).json({ message: "服务器错误" });
  }
});

// 获取用户交易历史
router.get("/history", authenticateToken, async (req, res) => {
  try {
    const userId = req.user.id;

    // 查询用户交易历史
    const [transactions] = await pool.query(
      "SELECT * FROM transactions WHERE user_id = ? ORDER BY created_at DESC",
      [userId]
    );

    res.json(transactions);
  } catch (error) {
    logger.error(`获取交易历史错误: ${error.message}`, { error: error.stack });
    res.status(500).json({ message: "服务器错误" });
  }
});

module.exports = router;
